home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / PortEditor.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  26KB  |  983 lines

  1. /*
  2.  * $Id: PortEditor.c,v 1.3 1992/10/28 12:28:44 mallet Exp $
  3.  *
  4.  * Copyright 1992 Lionel Mallet
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appears in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of Lionel MALLET not be used in
  11.  * advertising or publicity pertaining to distribution of the software
  12.  * without specific, written prior permission.  Lionel MALLET makes no
  13.  * representations about the suitability of this software for any
  14.  * purpose.  It is provided "as is" without express or implied warranty.
  15.  *
  16.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  17.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  19.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  20.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  21.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  22.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  *  This software is opened and free. Furthermore, everybody is kindly
  25.  * invited to participate to improve it for the benefit of all.
  26.  * Improvements can be new features, bugs fixes and porting issues
  27.  * resolution.
  28.  *
  29.  * Author:  Tim Wise - Scientific & Engineering Software (SES), Inc.
  30.  */
  31.  
  32. #include <string.h>
  33.  
  34. Boolean _PORTDEBUG = False;
  35.  
  36.  
  37. /*--------------------------------------------------------------------------*/
  38. /*
  39.             p o r t E d i t o r B u t t o n s
  40.  
  41.     Buttons for port editor.
  42. */
  43. /*--------------------------------------------------------------------------*/
  44.  
  45. static ButtonRec portEditorButtons[] = {
  46.  
  47. /* buttons ids */
  48.  
  49. #define kSetPort    0
  50. #define kClearPort    1
  51. #define kMovePort    2
  52. #define kPortInfo    3
  53.  
  54.   /* button recs  */
  55.   /* id,       name,        trap,   widget */
  56.  
  57.   { kSetPort,   "setPort",   TOGGLE, NULL },
  58.   { kClearPort, "clearPort", TOGGLE, NULL },
  59.   { kMovePort,  "movePort",  TOGGLE, NULL },
  60.   { kPortInfo,  "portInfo",  TOGGLE, NULL }
  61.  
  62. }; /* portEditorButtons */
  63.  
  64.  
  65.  
  66. /*****************************************************************************/
  67. /*
  68.             Port List Routines 
  69.  
  70.     A list of ports is kept in the XpmExtension format which is an
  71.     array of strings, one for each port. Convert string format
  72.     to Port structure when needed.
  73. */
  74. /*****************************************************************************/
  75.  
  76.  
  77. #define XpmPortName    "Ports"
  78. #define UNKNOWN        -1
  79.  
  80. typedef struct {
  81.     int       id;        /* unique number */
  82.     Position  x;        /* location of port */
  83.     Position  y;
  84.     char      info[256];     /* port info: name, kind */
  85. } Port;
  86.  
  87.  
  88. /*--------------------------------------------------------------------------*/
  89. /*
  90.             N e w P o r t 
  91.  
  92.     Allocate a new port structure including a string for info.
  93.     Return a pointer to allocated structure.
  94. */
  95. /*--------------------------------------------------------------------------*/
  96. Port *NewPort()
  97. {
  98.     Port *p;
  99.  
  100.     p = (Port *) XtNew(Port);
  101.     if (p != NULL) {
  102.         p->id = UNKNOWN;
  103.         p->x  = UNKNOWN;
  104.         p->y  = UNKNOWN;
  105.         p->info[0] = '\0';
  106.     }
  107.     return  p;
  108. }
  109.  
  110.  
  111. /*--------------------------------------------------------------------------*/
  112. /*
  113.             S t r T o P o r t
  114.  
  115.     Convert a string to a port structure. Return a pointer to the
  116.      port structure. NOTE: Caller must free structure!!
  117. */
  118. /*--------------------------------------------------------------------------*/
  119. Boolean StrToPort( str, p )
  120.     char *str;
  121.     Port *p;
  122. {
  123.     char *s, *t;
  124.     int  x, y;
  125.  
  126.     if (str != NULL && p != NULL) {
  127.  
  128.         sscanf( str, "%d%d%d",&p->id, &x, &y );
  129.         p->x = (Position) x;
  130.         p->y = (Position) y;
  131.         p->info[0] = '\0';
  132.  
  133.     s = XtMalloc( strlen(str) + 1 );    
  134.         strcpy( s, str );
  135.         t = strtok( s, " ," );         /* first token  id */
  136.         t = strtok( NULL, " ," );    /* second token x  */
  137.         t = strtok( NULL, " ," );    /* third token  y  */
  138.  
  139.         if (t != NULL && t+strlen(t)+1 < s+strlen(str)) 
  140.             strcpy( p->info, t+strlen(t)+1 );/* stuff after tokens */
  141.         
  142.         return True;
  143.  
  144.     } else 
  145.         return False;
  146. }
  147.  
  148.  
  149. /*--------------------------------------------------------------------------*/
  150. /*
  151.             P o r t T o S t r
  152.  
  153.     Convert a port structure to a string. Return pointer to string.
  154.     Caller must free string.
  155. */
  156. /*--------------------------------------------------------------------------*/
  157. char *PortToStr( p )
  158.     Port *p;
  159. {
  160.     char id_str[40];
  161.     char x_str[40];
  162.     char y_str[40];
  163.     char *str = NULL;
  164.  
  165.     if (p != NULL) {
  166.         sprintf( id_str, "%d\0", p->id );
  167.         sprintf( x_str,  "%d\0", p->x );
  168.         sprintf( y_str,  "%d\0", p->y );
  169.     str = XtMalloc( strlen(x_str) + strlen(y_str) + strlen(id_str)
  170.                         + strlen(p->info) + 4 );
  171.         str[0] = '\0';
  172.         strcat( str, id_str  );
  173.         strcat( str, " "     );
  174.         strcat( str, x_str   );
  175.         strcat( str, " "     );
  176.         strcat( str, y_str   );
  177.         strcat( str, " "     );
  178.         strcat( str, p->info );
  179.     }
  180.     return str;
  181. }
  182.  
  183.  
  184. /*--------------------------------------------------------------------------*/
  185. /*
  186.             U p d a t e P o r t 
  187.  
  188.     Replace string version of port i with info given in port structure.
  189. */
  190. /*--------------------------------------------------------------------------*/
  191. void UpdatePort( ports, i, p )
  192.     XpmExtension *ports;
  193.     int          i;
  194.     Port         *p;
  195. {
  196.     XtFree( ports->lines[i] );
  197.     ports->lines[i] = PortToStr( p );
  198. }
  199.  
  200.  
  201. /*--------------------------------------------------------------------------*/
  202. /*
  203.             F i n d P o r t 
  204.  
  205.     Search a list of ports and find the first at location (x,y).
  206.     If found, return index of port; otherwise return UNKNOWN.
  207. */
  208. /*--------------------------------------------------------------------------*/
  209. int FindPort( ports, at_x, at_y )
  210.     XpmExtension *ports;
  211.     Position     at_x;
  212.     Position     at_y;
  213. {
  214.     int   i;
  215.     int   x;
  216.     int   y;
  217.     Port  p;
  218.  
  219.     if (strcmp(ports->name, XpmPortName) == 0) {
  220.         for (i=0; i < ports->nlines ; i++) {
  221.             if ( StrToPort(ports->lines[i], &p) 
  222.                  && p.x == at_x && p.y == at_y ) {
  223.                 return i;
  224.             }
  225.         }
  226.     }
  227.     return UNKNOWN;
  228. }
  229.  
  230.  
  231. /*--------------------------------------------------------------------------*/
  232. /*
  233.              I s P o r t 
  234.  
  235.     See if a port exists at location (x,y). 
  236. */
  237. /*--------------------------------------------------------------------------*/
  238.  
  239. Boolean IsPort( w, x, y, return_ports, return_port_i )
  240.     Widget       w;
  241.     Position     x;
  242.     Position     y;
  243.     XpmExtension **return_ports;    /* list of ports; can be NULL! */
  244.     int          *return_port_i;    /* index of port x,y; can be NULL! */
  245. {
  246.     Boolean      result = False;
  247.     XpmExtension *ports = NULL;
  248.     int         i;
  249.  
  250.     /* if given a list of ports, use them; else get ports from widget */
  251.     if ( return_ports != NULL && *return_ports != NULL ) 
  252.         ports = *return_ports;
  253.     else 
  254.         ports = PWFindExtension( w, XpmPortName );
  255.     
  256.     if ( ports != NULL ) { 
  257.        if ( (i=FindPort(ports, x, y)) >= 0 ) {
  258.            result = True;
  259.        }
  260.     }
  261.  
  262.     if ( return_port_i != NULL )
  263.         *return_port_i = i;
  264.  
  265.     if ( return_ports != NULL ) 
  266.         *return_ports = ports;
  267.  
  268.     else if ( ports != NULL )
  269.         XpmFreeExtensions( ports, 1 );    /* free ports if caller */
  270.                                         /* doesn't want them    */
  271.     return result;
  272. }
  273.  
  274.  
  275. /*--------------------------------------------------------------------------*/
  276. /*
  277.             A d d P o r t
  278.  
  279.     Add a port to end of list. Return index of new port.
  280. */
  281. /*--------------------------------------------------------------------------*/
  282. int AddPort( ports, at_x, at_y )
  283.     XpmExtension *ports;
  284.     Position     at_x;
  285.     Position     at_y;
  286. {
  287.     Port *p;
  288.     char *port_str;
  289.     int  i = UNKNOWN;
  290.  
  291.     if ((p=NewPort()) != NULL) {
  292.  
  293.         p->x  = at_x;
  294.         p->y  = at_y;
  295.         p->id = 0;        /* mark as new port */
  296.  
  297.         if ( (port_str=PortToStr(p)) != NULL ) {
  298.  
  299.            i = ports->nlines;
  300.            ports->nlines++;
  301.  
  302.            if (ports->lines != NULL)
  303.                ports->lines = (char **) XtRealloc( 
  304.                                            (char *)ports->lines, 
  305.                                            ports->nlines * sizeof(char*) );
  306.            else 
  307.                ports->lines = (char **) XtNew( char** );
  308.  
  309.            ports->lines[i] = port_str;
  310.         }
  311.         XtFree((char *)p);
  312.     }
  313.     return i;
  314.  
  315.  
  316.  
  317. /*--------------------------------------------------------------------------*/
  318. /*
  319.             D e l P o r t
  320.  
  321.     Delete port i. Shift array elements above i to the left.
  322. */
  323. /*--------------------------------------------------------------------------*/
  324. void DelPort( ports, i )
  325.     XpmExtension *ports;
  326.     int          i;
  327. {
  328.     char **s, **t, **last;
  329.  
  330.     XtFree( ports->lines[i] );
  331.  
  332.     last = ports->lines + ports->nlines;    /* last element */
  333.     ports->nlines--;
  334.  
  335.     /* shift left elements above deletion, if necessary */
  336.     if (ports->nlines > 0) 
  337.         for (t = ports->lines+i, s = ports->lines+i+1; s < last; *t++ = *s++);
  338.     else {
  339.         XtFree( (char *)ports->lines );
  340.         ports->lines = NULL;
  341.     }
  342.  
  343.  
  344. /*--------------------------------------------------------------------------*/
  345. /*
  346.             T r a n s l a t e P o r t
  347.  
  348.     Add offsets dx and dy to location of port i.
  349. */
  350. /*--------------------------------------------------------------------------*/
  351. void TranslatePort( ports, port_i, dx, dy )
  352.     XpmExtension *ports;
  353.     int port_i;
  354.     int dx;
  355.     int dy;
  356. {
  357.     Port p;
  358.  
  359.     if ( StrToPort(ports->lines[port_i], &p) ) {
  360.         p.x += dx;
  361.         p.y += dy;
  362.         UpdatePort( ports, port_i, &p );
  363.     }
  364. }
  365.  
  366.  
  367. /*--------------------------------------------------------------------------*/
  368. /*
  369.                         P r i n t P o r t s
  370. */
  371. /*--------------------------------------------------------------------------*/
  372. void PrintPorts( ports )
  373.     XpmExtension *ports;
  374. {
  375.     fprintf( stderr, "ports:\n" );
  376.     if ( ports ) {
  377.         int i;
  378.         for (i = 0; i < ports->nlines; i++) 
  379.             fprintf(stderr, "\t\t%s\n", ports->lines[i]);
  380.     }
  381. }
  382.  
  383.  
  384.  
  385. /*****************************************************************************/
  386. /*
  387.         Port Editor Interface Routines 
  388. */
  389. /*****************************************************************************/
  390.  
  391.  
  392. /*--------------------------------------------------------------------------*/
  393. /*
  394.             P o r t S h a p e
  395.  
  396.     Return an array of points defining a port's shape.
  397. */
  398. /*--------------------------------------------------------------------------*/
  399.  
  400. #define NPortPoints 7
  401.  
  402. XPoint *PortShape( w, x ,y )
  403.     Widget    w;
  404.     Position    x; 
  405.     Position    y;
  406. {
  407.     static XPoint points[NPortPoints];
  408.     int   i;
  409.     float fx = x;
  410.     float fy = y;
  411.  
  412.     points[0].x = PWInWindowX( w, fx );
  413.     points[0].y = PWInWindowY( w, fy );
  414.     points[1].x = PWInWindowX( w, fx + 0.5 );
  415.     points[1].y = PWInWindowY( w, fy + 0.5 );
  416.     points[2].x = PWInWindowX( w, fx );
  417.     points[2].y = PWInWindowY( w, fy + 1 );
  418.     points[3].x = PWInWindowX( w, fx + 1 );
  419.     points[3].y = PWInWindowY( w, fy + 1 );
  420.     points[4].x = PWInWindowX( w, fx + 0.5 );
  421.     points[4].y = PWInWindowY( w, fy + 0.5 );
  422.     points[5].x = PWInWindowX( w, fx + 1 );
  423.     points[5].y = PWInWindowY( w, fy );
  424.     points[6].x = PWInWindowX( w, fx );
  425.     points[6].y = PWInWindowY( w, fy );
  426.  
  427. /*
  428.     fprintf( stderr, "PortShape:\n" );
  429.     for ( i=0; i < NPortPoints; i++ )
  430.         fprintf( stderr, "\t\t%d, %d\n", points[i].x, points[i].y );
  431. */
  432.  
  433.     return points;
  434. }
  435.  
  436.  
  437. /*--------------------------------------------------------------------------*/
  438. /*
  439.             D r a w P o r t 
  440.  
  441.     Just draw a port a location (x,y) with given value (set, clear, 
  442.     invert, or highlight). 
  443. */
  444. /*--------------------------------------------------------------------------*/
  445. #if NeedFunctionPrototypes
  446. void DrawPort(Widget w, Position x, Position y, int value)
  447. #else
  448. void DrawPort(w, x, y, value )
  449.     Widget   w;
  450.     Position x;
  451.     Position y;
  452.     int      value;
  453. #endif
  454. {
  455.     GC gc;
  456.  
  457. /*
  458.     if (_PORTDEBUG)
  459.         printf( "DrawPort: %d %d \n", x, y );
  460. */
  461.  
  462.     gc = (value == Highlight) ? PWHighlightingGC(w) : PWFramingGC(w);
  463.  
  464.     XFillPolygon( XtDisplay(w), XtWindow(w), gc,
  465.                   PortShape(w, x, y), NPortPoints, 
  466.                   Convex, CoordModeOrigin );
  467. }
  468.  
  469.  
  470. /*--------------------------------------------------------------------------*/
  471. /*
  472.             D r a w I f P o r t 
  473.  
  474.     Draw a port at location (x,y) if there is a port at that 
  475.     location. This routine is used to highlight a port that a
  476.     user is trying to pick.
  477. */
  478. /*--------------------------------------------------------------------------*/
  479. #if NeedFunctionPrototypes
  480. void DrawIfPort(Widget w, Position x, Position y, int value )
  481. #else
  482. void DrawIfPort( w, x, y, value )
  483.     Widget   w;
  484.     Position x;
  485.     Position y;
  486.     int      value;
  487. #endif
  488. {
  489.     if ( IsPort(w, x, y, NULL, NULL) )
  490.         DrawPort( w, x, y, value );
  491.  
  492.  
  493. /*--------------------------------------------------------------------------*/
  494. /*
  495.             S e t P o r t 
  496.  
  497.     Create and draw a port at (x,y) if there is not already a port
  498.     there. 
  499. */
  500. /*--------------------------------------------------------------------------*/
  501. #if NeedFunctionPrototypes
  502. void SetPort(Widget w, Position x, Position y, int value )
  503. #else
  504. void SetPort( w, x, y, value )
  505.     Widget   w;
  506.     Position x;
  507.     Position y;
  508.     int      value;
  509. #endif
  510. {
  511.     XpmExtension *ports = NULL;
  512.  
  513.     if (_PORTDEBUG)
  514.         printf( "SetPort: %d,%d \n", x, y );
  515.  
  516.     if ( !IsPort(w, x, y, &ports, NULL) ) {
  517.         if (ports == NULL) {
  518.             PWAddExtension( w, XpmPortName );
  519.             ports = PWFindExtension( w, XpmPortName );
  520.         }
  521.  
  522.         AddPort( ports, x, y );
  523.         DrawPort( w, x, y, value );
  524.  
  525.     if (_PORTDEBUG)
  526.             PrintPorts( ports );
  527.  
  528.         PWUpdateExtension( w, ports );
  529.     XpmFreeExtensions( ports, 1 );
  530.     }
  531.  
  532.  
  533. /*--------------------------------------------------------------------------*/
  534. /*
  535.             C l e a r P o r t 
  536.  
  537.     Delete the port at (x,y) from the port list and erase the port 
  538.     on the screen.
  539. */
  540. /*--------------------------------------------------------------------------*/
  541. #if NeedFunctionPrototypes
  542. void ClearPort(Widget w, Position x, Position y, int value )
  543. #else
  544. void ClearPort( w, x, y, value )
  545.     Widget   w;
  546.     Position x;
  547.     Position y;
  548.     int      value;
  549. #endif
  550. {
  551.     XpmExtension *ports = NULL;
  552.     int          port_i;
  553.  
  554.     if (_PORTDEBUG)
  555.         printf("ClearPort : %d,%d \n", x, y);
  556.  
  557.     if ( IsPort(w, x, y, &ports, &port_i) ) { 
  558.  
  559.         DelPort( ports, port_i );
  560.         DrawPort( w, x, y, value );    /* erase */
  561.  
  562.     if (_PORTDEBUG)
  563.             PrintPorts( ports );
  564.  
  565.         if ( ports->nlines == 0 )
  566.             PWRemoveExtension( w, XpmPortName );
  567.         else
  568.             PWUpdateExtension( w, ports );
  569.     XpmFreeExtensions( ports, 1 );
  570.     }
  571. }
  572.  
  573.  
  574. /*--------------------------------------------------------------------------*/
  575. /*
  576.             D r a g P o r t 
  577.  
  578.     Draw a port while the user is dragging. Draw only if a port existed
  579.     at the starting location of the drag. 
  580. */
  581. /*--------------------------------------------------------------------------*/
  582.  
  583. static struct {
  584.  
  585.     Boolean  b;        /* Are we dragging a port?  */
  586.     Position from_x;    /* starting point of drag   */
  587.     Position from_y;    
  588.     int      port_i;    /* which port is being dragged */
  589.  
  590. } dragging = { False, UNKNOWN, UNKNOWN, UNKNOWN };
  591.  
  592.  
  593. #if NeedFunctionPrototypes
  594. void DragPort(Widget w, Position x, Position y, int value )
  595. #else
  596. void DragPort( w, x, y, value )
  597.     Widget   w;
  598.     Position x;
  599.     Position y;
  600.     int      value;
  601. #endif
  602. {
  603.     int      i;
  604.  
  605.     /* if beginning of drag a port, ... */
  606.     if ( dragging.b == False && IsPort(w, x, y, NULL, &i) ) {
  607.  
  608.         dragging.b      = True;
  609.     dragging.from_x = x;
  610.     dragging.from_y = y;
  611.         dragging.port_i = i;
  612.     }
  613.  
  614.     if (dragging.b) {
  615.         DrawPort( w, dragging.from_x, dragging.from_y, value );/* erase */
  616.         DrawPort( w, x, y, value );/* draw */
  617.     }
  618. }
  619.  
  620. /*--------------------------------------------------------------------------*/
  621. /*
  622.             M o v e P o r t 
  623.  
  624.     Move a port from one location to another after user has completed
  625.     dragging.
  626. */
  627. /*--------------------------------------------------------------------------*/
  628. #if NeedFunctionPrototypes
  629. void MovePort(Widget w, Position to_x, Position to_y, int value )
  630. #else
  631. void MovePort( w, to_x, to_y, value )
  632.     Widget   w;
  633.     Position to_x;
  634.     Position to_y;
  635.     int      value;
  636. #endif
  637. {
  638.     XpmExtension *ports = NULL;
  639.     Port         p;
  640.  
  641.     if (_PORTDEBUG)
  642.         printf("MovePort : from %d,%d to %d,%d \n", 
  643.                 dragging.from_x, dragging.from_y, to_x, to_y);
  644.  
  645.     if ( dragging.b
  646.          && !IsPort(w, to_x, to_y, &ports, NULL)  ) {
  647.  
  648.         DrawPort( w, dragging.from_x, dragging.from_y, value );/* erase old */
  649.         DrawPort( w, to_x, to_y, value );                   /* draw  new */
  650.  
  651.         TranslatePort( ports, dragging.port_i, 
  652.                        to_x - dragging.from_x, 
  653.                        to_y - dragging.from_y  );
  654.  
  655.         PWUpdateExtension( w, ports );
  656.     XpmFreeExtensions( ports, 1 );
  657.     if (_PORTDEBUG)
  658.             PrintPorts( ports );
  659.     }
  660.     dragging.b      = False;
  661.     dragging.from_x = UNKNOWN;
  662.     dragging.from_y = UNKNOWN;
  663.     dragging.port_i = UNKNOWN;
  664. }
  665.  
  666.  
  667. /*--------------------------------------------------------------------------*/
  668. /*
  669.             P o r t I n f o
  670.  
  671.     Allow the user to edit the port information for the port at (x,y).
  672. */
  673. /*--------------------------------------------------------------------------*/
  674.  
  675. #if NeedFunctionPrototypes
  676. void PortInfo(Widget w, Position x, Position y, int value )
  677. #else
  678. void PortInfo( w, x, y, value )
  679.     Widget   w;
  680.     Position x;
  681.     Position y;
  682.     int      value;
  683. #endif
  684. {
  685.     XpmExtension *ports = NULL;
  686.     Port         p;
  687.     int          i;
  688.     char         *newInfo;
  689.  
  690.     if (_PORTDEBUG)
  691.         printf("PortInfo : %d,%d\n", x, y);
  692.  
  693.     if ( IsPort(w, x, y, &ports, &i) ) { 
  694.         StrToPort( ports->lines[i], &p );
  695.         if ( PopupDialog( input_dialog, 
  696.                           "Port Info: <name> <kind>",
  697.                            p.info, &newInfo,
  698.                           XtGrabExclusive) == Okay ) {
  699.         strcpy( p.info, newInfo );
  700.             UpdatePort( ports, i, &p ); 
  701.         }
  702.     if (_PORTDEBUG)
  703.             PrintPorts( ports );
  704.         PWUpdateExtension( w, ports );
  705.     XpmFreeExtensions( ports, 1 );
  706.     }
  707. }
  708.  
  709.  
  710. /*--------------------------------------------------------------------------*/
  711. /*
  712.             R e d r a w P o r t s
  713.  
  714.     Redraw all ports of PixmapWidget.
  715. */
  716. /*--------------------------------------------------------------------------*/
  717.  
  718. void RedrawPorts( w, value )
  719.     Widget w;
  720.     int    value;
  721. {
  722.     XpmExtension *ports = NULL;
  723.     Port         p;
  724.     int          i;
  725.  
  726.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  727.         for ( i=0; i < ports->nlines; i++ ) { 
  728.             StrToPort( ports->lines[i], &p );
  729.             DrawPort( w, p.x, p.y, value ); 
  730.         }
  731.     }
  732. }
  733.  
  734.  
  735. /*--------------------------------------------------------------------------*/
  736. /*
  737.             T r a n s l a t e P o r t s 
  738.  
  739.     For all ports in PixmapWidget, add dx,dy to the ports location.
  740. */
  741. /*--------------------------------------------------------------------------*/
  742.  
  743. void TranslatePorts( w, dx, dy )
  744.     Widget    w;
  745.     Position    dx;
  746.     Position    dy;
  747. {
  748.     XpmExtension *ports = NULL;
  749.     Port         p;
  750.     int          i;
  751.  
  752.     if (_PORTDEBUG)
  753.         printf("TranslatePorts : %d,%d\n", dx, dy);
  754.  
  755.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  756.         for ( i=0; i < ports->nlines; i++ ) { 
  757.             StrToPort( ports->lines[i], &p );
  758.  
  759.             DrawPort( w, p.x, p.y, Clear );        /* erase old */
  760.             PWTranslatePoint( w, &p.x, &p.y, dx, dy ); 
  761.             DrawPort( w, p.x, p.y, Set );        /* draw new */
  762.  
  763.         UpdatePort( ports, i, &p );
  764.         }
  765.     if (_PORTDEBUG)
  766.             PrintPorts( ports );
  767.         PWUpdateExtension( w, ports );
  768.     XpmFreeExtensions( ports, 1 );
  769.     }
  770.  
  771. }
  772.  
  773.  
  774. /*--------------------------------------------------------------------------*/
  775. /*
  776.             F l i p P o r t s 
  777.  
  778.     Flip all ports of a PixmapWidget either horiziontally or vertically.
  779. */
  780. /*--------------------------------------------------------------------------*/
  781.  
  782. void FlipPorts( w, axis  )
  783.     Widget         w;
  784.     enum FlipAxis    axis;
  785. {
  786.     XpmExtension *ports = NULL;
  787.     Port         p;
  788.     int          i;
  789.  
  790.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  791.         for ( i=0; i < ports->nlines; i++ ) { 
  792.             StrToPort( ports->lines[i], &p );
  793.  
  794.             DrawPort( w, p.x, p.y, Clear );        /* erase old */
  795.             PWFlipPoint( w, &p.x, &p.y, axis ); 
  796.             DrawPort( w, p.x, p.y, Set );        /* draw new */
  797.  
  798.         UpdatePort( ports, i, &p );
  799.         }
  800.     if (_PORTDEBUG)
  801.             PrintPorts( ports );
  802.         PWUpdateExtension( w, ports );
  803.     XpmFreeExtensions( ports, 1 );
  804.     }
  805. }
  806.  
  807.  
  808. /*--------------------------------------------------------------------------*/
  809. /*
  810.             R o t a t e P o r t s 
  811.  
  812.     Flip all ports of a PixmapWidget either left or right 90 degrees.
  813. */
  814. /*--------------------------------------------------------------------------*/
  815.  
  816. void RotatePorts( w, direction )
  817.     Widget            w;
  818.     enum RotateDirection    direction;
  819. {
  820.     XpmExtension *ports = NULL;
  821.     Port         p;
  822.     int          i;
  823.  
  824.     if ( (ports=PWFindExtension( w, XpmPortName )) != NULL ) { 
  825.         for ( i=0; i < ports->nlines; i++ ) { 
  826.             StrToPort( ports->lines[i], &p );
  827.  
  828.             DrawPort( w, p.x, p.y, Clear );        /* erase old */
  829.             PWRotatePoint( w, &p.x, &p.y, direction ); 
  830.             DrawPort( w, p.x, p.y, Set );        /* draw new */
  831.  
  832.         UpdatePort( ports, i, &p );
  833.         }
  834.     if (_PORTDEBUG)
  835.             PrintPorts( ports );
  836.         PWUpdateExtension( w, ports );
  837.     XpmFreeExtensions( ports, 1 );
  838.     }
  839. }
  840.  
  841.  
  842. /*--------------------------------------------------------------------------*/
  843. /*
  844.             P o r t E d i t o r C a l l b a c k
  845.  
  846.     Callback for all port editor buttons
  847. */
  848. /*--------------------------------------------------------------------------*/
  849. void PortEditorCallback( w, client_data, call_data )
  850.     Widget w;
  851.     XtPointer client_data, call_data;
  852. {
  853.     int *id = (int *)client_data;
  854.  
  855.     switch (*id) {
  856.  
  857.  
  858.     case kSetPort:
  859.     if (_PORTDEBUG)
  860.             printf( "PortEditorCallback: %s\n", portEditorButtons[*id].name );
  861.         PWRemoveAllRequests( pixmap_widget );
  862.  
  863.     PWSetPickPixelDrawProc( pixmap_widget, DrawPort );
  864.     PWSetPickPixelCompleteProc( pixmap_widget, SetPort );
  865.  
  866.         PWEngageRequest( pixmap_widget, PickPixelRequest, True, Plain );
  867.         break;
  868.  
  869.     case kClearPort:
  870.     if (_PORTDEBUG)
  871.             printf( "PortEditorCallback: %s\n", portEditorButtons[*id].name );
  872.         PWRemoveAllRequests( pixmap_widget );
  873.  
  874.     PWSetPickPixelDrawProc( pixmap_widget, DrawIfPort );
  875.     PWSetPickPixelCompleteProc( pixmap_widget, ClearPort );
  876.  
  877.         PWEngageRequest( pixmap_widget, PickPixelRequest, True, Plain );
  878.         break;
  879.  
  880.     case kMovePort:
  881.     if (_PORTDEBUG)
  882.             printf( "PortEditorCallback: %s\n", portEditorButtons[*id].name );
  883.         PWRemoveAllRequests( pixmap_widget );
  884.  
  885.     PWSetPickPixelDrawProc( pixmap_widget, DragPort );
  886.     PWSetPickPixelCompleteProc( pixmap_widget, MovePort );
  887.  
  888.         PWEngageRequest( pixmap_widget, PickPixelRequest, True, Plain );
  889.     break;
  890.  
  891.     case kPortInfo:
  892.     if (_PORTDEBUG)
  893.             printf( "PortEditorCallback: %s\n", portEditorButtons[*id].name );
  894.         PWRemoveAllRequests( pixmap_widget );
  895.  
  896.     PWSetPickPixelDrawProc( pixmap_widget, DrawIfPort );
  897.     PWSetPickPixelCompleteProc( pixmap_widget, PortInfo );
  898.  
  899.         PWEngageRequest( pixmap_widget, PickPixelRequest, True, Plain );
  900.     break;
  901.  
  902.     default:
  903.         printf( "PortEditorCallback: invalid id = %d\n", *id );
  904.     } /* switch */
  905.  
  906. } /* PortEditorCallback */
  907.  
  908.  
  909.  
  910. /*--------------------------------------------------------------------------*/
  911. /*
  912.         C r e a t e P o r t E d i t o r B u t t o n s
  913.  
  914.     Create buttons of port editor.
  915. */
  916. /*--------------------------------------------------------------------------*/
  917. void CreatePortEditorButtons( parentW, radioGroupW )
  918.     Widget    parentW;    /* parent widget of port editor buttons */
  919.     Widget    radioGroupW;    /* radio group to add port editor buttons */
  920. {
  921.     int    i;
  922.     Widget w;
  923.  
  924.     for (i = 0; i < XtNumber(portEditorButtons); i++) {
  925.  
  926. #ifndef USE_ATHENA
  927.     w = XmCreateToggleButtonGadget(parentW, portEditorButtons[i].name,
  928.                        NULL, 0);
  929.     XtManageChild(w);
  930.         portEditorButtons[i].widget = w;
  931.  
  932.         XtAddCallback(w, XmNvalueChangedCallback, PortEditorCallback,
  933.               &portEditorButtons[i].id );
  934.     
  935. #else
  936.         w = XtCreateWidget( portEditorButtons[i].name,
  937.                             toggleWidgetClass,
  938.                             parentW, NULL, 0 );
  939.  
  940.         portEditorButtons[i].widget = w;
  941.  
  942.         XtAddCallback( w, 
  943.                XtNcallback, PortEditorCallback,
  944.                        &portEditorButtons[i].id );
  945.  
  946.     /* add to button to radio group */
  947.     XtVaSetValues( w,
  948.                XtNradioGroup, radioGroupW,
  949.                NULL );
  950. #endif
  951.     } 
  952.  
  953.  
  954.  
  955. /*--------------------------------------------------------------------------*/
  956. /*
  957.         M a n a g e P o r t E d i t o r B u t t o n s
  958.  
  959.     Manage or unmanage the buttons of port editor depending on flag.
  960. */
  961. /*--------------------------------------------------------------------------*/
  962. void ManagePortEditorButtons( manage )
  963.     Boolean    manage;        /* if true, manage; otherwise unmanage */
  964. {
  965.     int    i;
  966.     Widget w;
  967.  
  968.     for (i = 0; i < XtNumber(portEditorButtons); i++) {
  969.     if (manage) 
  970.             XtManageChild( portEditorButtons[i].widget );
  971.         else 
  972.             XtUnmanageChild( portEditorButtons[i].widget );
  973.     } 
  974. }
  975.  
  976.  
  977.  
  978.